-- Lua Battle System - 目标选择算法
-- 支持多种目标选择模式，如单体、群体、随机等

local Logger = require("utils.logger")
local Errors = require("utils.errors")

local TargetSelector = {
    -- 目标选择模式
    modes = {
        SINGLE = "single", -- 单体目标
        MULTIPLE = "multiple", -- 多个目标
        ALL = "all", -- 所有目标
        SELF = "self", -- 自身
        RANDOM = "random", -- 随机目标
        LOWEST_HP = "lowest_hp", -- 最低生命值
        HIGHEST_HP = "highest_hp", -- 最高生命值
        LOWEST_MP = "lowest_mp", -- 最低魔法值
        HIGHEST_MP = "highest_mp", -- 最高魔法值
        LOWEST_ATK = "lowest_atk", -- 最低攻击力
        HIGHEST_ATK = "highest_atk" -- 最高攻击力
    }
}

-- 目标选择构造函数
function TargetSelector:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self
    return o
end

-- 选择目标
-- @param caster 施法者
-- @param targets 可选目标列表
-- @param mode 选择模式
-- @param skill 技能对象
-- @return table 选择的目标列表
function TargetSelector:select_targets(caster, targets, mode, skill)
    Logger.debug("选择目标，模式: " .. mode)
    
    -- 检查参数
    if not caster or not targets or not mode then
        Logger.error("目标选择参数不完整")
        return nil
    end
    
    -- 根据选择模式选择目标
    local selected_targets = {}
    
    if mode == self.modes.SINGLE then
        selected_targets = self:select_single_target(caster, targets, skill)
    elseif mode == self.modes.MULTIPLE then
        selected_targets = self:select_multiple_targets(caster, targets, skill)
    elseif mode == self.modes.ALL then
        selected_targets = self:select_all_targets(caster, targets, skill)
    elseif mode == self.modes.SELF then
        selected_targets = self:select_self_target(caster, targets, skill)
    elseif mode == self.modes.RANDOM then
        selected_targets = self:select_random_targets(caster, targets, skill)
    elseif mode == self.modes.LOWEST_HP then
        selected_targets = self:select_lowest_hp_targets(caster, targets, skill)
    elseif mode == self.modes.HIGHEST_HP then
        selected_targets = self:select_highest_hp_targets(caster, targets, skill)
    elseif mode == self.modes.LOWEST_MP then
        selected_targets = self:select_lowest_mp_targets(caster, targets, skill)
    elseif mode == self.modes.HIGHEST_MP then
        selected_targets = self:select_highest_mp_targets(caster, targets, skill)
    elseif mode == self.modes.LOWEST_ATK then
        selected_targets = self:select_lowest_atk_targets(caster, targets, skill)
    elseif mode == self.modes.HIGHEST_ATK then
        selected_targets = self:select_highest_atk_targets(caster, targets, skill)
    else
        Logger.error("未知的目标选择模式: " .. mode)
        return nil
    end
    
    return selected_targets
end

-- 选择单体目标
function TargetSelector:select_single_target(caster, targets, skill)
    local selected = {}
    
    -- 如果只有一个目标，直接选择
    if #targets == 1 then
        table.insert(selected, targets[1])
        return selected
    end
    
    -- 否则选择第一个目标（默认行为，实际使用中应该由玩家或AI选择）
    table.insert(selected, targets[1])
    return selected
end

-- 选择多个目标
function TargetSelector:select_multiple_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 限制目标数量
    local target_count = math.min(max_targets, #targets)
    
    -- 选择前N个目标（默认行为，实际使用中应该由玩家或AI选择）
    for i = 1, target_count do
        table.insert(selected, targets[i])
    end
    
    return selected
end

-- 选择所有目标
function TargetSelector:select_all_targets(caster, targets, skill)
    return targets
end

-- 选择自身为目标
function TargetSelector:select_self_target(caster, targets, skill)
    -- 检查施法者是否在目标列表中
    for _, target in ipairs(targets) do
        if target.id == caster.id then
            return {target}
        end
    end
    
    -- 如果施法者不在目标列表中，返回空列表
    Logger.warn("施法者不在目标列表中")
    return {}
end

-- 选择随机目标
function TargetSelector:select_random_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 复制目标列表，避免修改原列表
    local available_targets = {}
    for _, target in ipairs(targets) do
        table.insert(available_targets, target)
    end
    
    -- 随机选择目标
    local target_count = math.min(max_targets, #available_targets)
    for i = 1, target_count do
        if #available_targets == 0 then
            break
        end
        
        local random_index = math.random(1, #available_targets)
        table.insert(selected, available_targets[random_index])
        table.remove(available_targets, random_index)
    end
    
    return selected
end

-- 选择最低生命值目标
function TargetSelector:select_lowest_hp_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按生命值排序（升序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        return a.hp / a.max_hp < b.hp / b.max_hp 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 选择最高生命值目标
function TargetSelector:select_highest_hp_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按生命值排序（降序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        return a.hp / a.max_hp > b.hp / b.max_hp 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 选择最低魔法值目标
function TargetSelector:select_lowest_mp_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按魔法值排序（升序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        return a.mp / a.max_mp < b.mp / b.max_mp 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 选择最高魔法值目标
function TargetSelector:select_highest_mp_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按魔法值排序（降序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        return a.mp / a.max_mp > b.mp / b.max_mp 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 选择最低攻击力目标
function TargetSelector:select_lowest_atk_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按攻击力排序（升序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        local atk_a = a.attack + (a.magic_attack or 0)
        local atk_b = b.attack + (b.magic_attack or 0)
        return atk_a < atk_b 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 选择最高攻击力目标
function TargetSelector:select_highest_atk_targets(caster, targets, skill)
    local selected = {}
    local max_targets = skill.max_targets or 1
    
    -- 按攻击力排序（降序）
    local sorted_targets = {}
    for _, target in ipairs(targets) do
        table.insert(sorted_targets, target)
    end
    
    table.sort(sorted_targets, function(a, b) 
        local atk_a = a.attack + (a.magic_attack or 0)
        local atk_b = b.attack + (b.magic_attack or 0)
        return atk_a > atk_b 
    end)
    
    -- 选择前N个目标
    local target_count = math.min(max_targets, #sorted_targets)
    for i = 1, target_count do
        table.insert(selected, sorted_targets[i])
    end
    
    return selected
end

-- 获取可用目标列表
-- @param caster 施法者
-- @param all_characters 所有角色列表
-- @param skill 技能对象
-- @return table 可用目标列表
function TargetSelector:get_available_targets(caster, all_characters, skill)
    local available_targets = {}
    local target_type = skill.target_type or "enemy"
    
    -- 根据目标类型过滤目标
    for _, character in ipairs(all_characters) do
        ::continue::
        -- 跳过已阵亡的角色
        if not character.is_alive then
            goto continue
        end
        
        -- 根据目标类型选择
        if target_type == "enemy" then
            -- 选择敌方角色
            if character.team_id ~= caster.team_id then
                table.insert(available_targets, character)
            end
        elseif target_type == "ally" then
            -- 选择友方角色
            if character.team_id == caster.team_id then
                table.insert(available_targets, character)
            end
        elseif target_type == "any" then
            -- 选择任何角色
            table.insert(available_targets, character)
        elseif target_type == "self" then
            -- 只选择自身
            if character.id == caster.id then
                table.insert(available_targets, character)
            end
        end
    end
    
    return available_targets
end

-- 验证目标是否有效
-- @param caster 施法者
-- @param target 目标角色
-- @param skill 技能对象
-- @return boolean 是否有效
function TargetSelector:is_valid_target(caster, target, skill)
    -- 检查目标是否存活
    if not target.is_alive then
        return false
    end
    
    -- 检查目标类型
    local target_type = skill.target_type or "enemy"
    if target_type == "enemy" and target.team_id == caster.team_id then
        return false
    elseif target_type == "ally" and target.team_id ~= caster.team_id then
        return false
    elseif target_type == "self" and target.id ~= caster.id then
        return false
    end
    
    return true
end

-- 导出模块
return TargetSelector
